﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace RFC2Namespace
{
    class Program
    {
        static void Main(string[] args)
        {
            long stime = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
            RFC2Game game01 = new RFC2Game();
            game01.Init();

            // 运行多回合测试
            for (int i = 0; i < 50; i++)
            {
                game01.DoTurn();
            }

            long etime = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
            Console.WriteLine($"总执行时长：{etime - stime} 毫秒.");
            Console.ReadKey();
        }
    }

    // A*寻路节点
    class PathNode : IComparable<PathNode>
    {
        public int x, y;
        public int gCost; // 起点到当前节点的实际代价
        public int hCost; // 当前节点到终点的预估代价
        public int fCost; // 总代价 f = g + h
        public PathNode parent;

        public PathNode(int x, int y)
        {
            this.x = x;
            this.y = y;
        }

        public int CompareTo(PathNode other)
        {
            return this.fCost.CompareTo(other.fCost);
        }

        public override bool Equals(object obj)
        {
            if (this == obj) return true;
            if (obj == null || GetType() != obj.GetType()) return false;
            PathNode node = (PathNode)obj;
            return x == node.x && y == node.y;
        }

        public override int GetHashCode()
        {
            return x * 31 + y;
        }
    }

    // A*寻路算法实现
    class AStarPathfinder
    {
        private const int MAP_SIZE = 100;
        private bool[,] obstacleMap; // 障碍物地图

        public AStarPathfinder()
        {
            obstacleMap = new bool[MAP_SIZE, MAP_SIZE];
            // 初始化障碍物地图（默认无障碍物）
            for (int x = 0; x < MAP_SIZE; x++)
            {
                for (int y = 0; y < MAP_SIZE; y++)
                {
                    obstacleMap[x, y] = false;
                }
            }
        }

        // 设置障碍物
        public void SetObstacle(int x, int y, bool isObstacle)
        {
            if (x >= 0 && x < MAP_SIZE && y >= 0 && y < MAP_SIZE)
            {
                obstacleMap[x, y] = isObstacle;
            }
        }

        // 计算从start到target的路径
        public List<PathNode> FindPath(int startX, int startY, int targetX, int targetY)
        {
            SortedSet<PathNode> openSet = new SortedSet<PathNode>();
            HashSet<PathNode> closedSet = new HashSet<PathNode>();

            PathNode startNode = new PathNode(startX, startY);
            PathNode targetNode = new PathNode(targetX, targetY);

            openSet.Add(startNode);

            while (openSet.Count > 0)
            {
                PathNode currentNode = openSet.First();
                openSet.Remove(currentNode);

                if (currentNode.Equals(targetNode))
                {
                    return ReconstructPath(currentNode);
                }

                closedSet.Add(currentNode);

                // 获取相邻节点（上下左右）
                List<PathNode> neighbors = GetNeighbors(currentNode);
                foreach (PathNode neighbor in neighbors)
                {
                    if (closedSet.Contains(neighbor) || obstacleMap[neighbor.x, neighbor.y])
                    {
                        continue;
                    }

                    int tentativeGCost = currentNode.gCost + 1; // 相邻节点的移动代价为1

                    if (tentativeGCost < neighbor.gCost || !openSet.Contains(neighbor))
                    {
                        neighbor.parent = currentNode;
                        neighbor.gCost = tentativeGCost;
                        neighbor.hCost = Heuristic(neighbor, targetNode);
                        neighbor.fCost = neighbor.gCost + neighbor.hCost;

                        if (!openSet.Contains(neighbor))
                        {
                            openSet.Add(neighbor);
                        }
                    }
                }
            }

            return null; // 没有找到路径
        }

        // 重建路径
        private List<PathNode> ReconstructPath(PathNode node)
        {
            List<PathNode> path = new List<PathNode>();
            PathNode current = node;

            while (current != null)
            {
                path.Insert(0, current); // 从终点回溯，所以要插入到列表头部
                current = current.parent;
            }

            return path;
        }

        // 获取相邻节点
        private List<PathNode> GetNeighbors(PathNode node)
        {
            List<PathNode> neighbors = new List<PathNode>();
            int x = node.x;
            int y = node.y;

            // 上
            if (y > 0) neighbors.Add(new PathNode(x, y - 1));
            // 下
            if (y < MAP_SIZE - 1) neighbors.Add(new PathNode(x, y + 1));
            // 左
            if (x > 0) neighbors.Add(new PathNode(x - 1, y));
            // 右
            if (x < MAP_SIZE - 1) neighbors.Add(new PathNode(x + 1, y));

            return neighbors;
        }

        // 启发式函数（曼哈顿距离）
        private int Heuristic(PathNode a, PathNode b)
        {
            return Math.Abs(a.x - b.x) + Math.Abs(a.y - b.y);
        }
    }

    class RFC2CivilizationType
    {
        public int m_civilization;

        public override bool Equals(object obj)
        {
            if (this == obj) return true;
            if (obj == null || GetType() != obj.GetType()) return false;
            RFC2CivilizationType other = (RFC2CivilizationType)obj;
            return m_civilization == other.m_civilization;
        }

        public override int GetHashCode()
        {
            return m_civilization;
        }
    }

    class RFC2City
    {
        public int m_x;
        public int m_y;
        public RFC2CivilizationType eOwner;
        public List<RFC2Plot> m_city_plot = new List<RFC2Plot>();
        private RFC2Game game;

        public void SetGame(RFC2Game game)
        {
            this.game = game;
        }

        public void Init(int x, int y)
        {
            m_x = x;
            m_y = y;
        }

        public void DoTurn()
        {
            if (game == null)
            {
                Console.WriteLine("游戏实例未初始化，无法统计单位");
                return;
            }

            int unitCount = CountUnitsWithinRange(3);
            game.m_count += unitCount;
        }

        private int CountUnitsWithinRange(int range)
        {
            List<RFC2Unit> unitsInRange = game.GetUnitsInRange(m_x, m_y, range);
            return unitsInRange.Count;
        }
    }

    class RFC2Plot
    {
        public int m_x;
        public int m_y;
        public RFC2CivilizationType eOwner;

        public RFC2Plot(int x, int y)
        {
            m_x = x;
            m_y = y;
        }

        public void DoTurn()
        {
        }
    }

    class RFC2Unit
    {
        public int m_x;
        public int m_y;
        public RFC2CivilizationType eOwner;
        private List<PathNode> currentPath; // 当前移动路径
        private AStarPathfinder pathfinder; // A*寻路器
        private RFC2Game game; // 游戏引用
        private int moveCooldown = 0; // 移动冷却

        public void SetGame(RFC2Game game)
        {
            this.game = game;
            this.pathfinder = new AStarPathfinder();
        }

        public void Init(int x, int y)
        {
            m_x = x;
            m_y = y;
        }

        public void DoTurn()
        {
            if (game == null) return;

            // 移动冷却机制
            if (moveCooldown > 0)
            {
                moveCooldown--;
                return;
            }

            // 每5个回合重新计算一次路径
            if (currentPath == null || currentPath.Count == 0)
            {
                RFC2Unit target = FindFarthestEnemyUnit();
                if (target != null)
                {
                    currentPath = CalculatePathTo(target.m_x, target.m_y);
                }
            }

            // 沿着路径移动一步
            MoveAlongPath();
        }

        // 寻找最远的非本国单位
        private RFC2Unit FindFarthestEnemyUnit()
        {
            List<RFC2Unit> allUnits = game.GetAllUnits();
            RFC2Unit farthestUnit = null;
            int maxDistance = 0;

            foreach (RFC2Unit unit in allUnits)
            {
                if (!unit.eOwner.Equals(this.eOwner)) // 非本国单位
                {
                    int distance = CalculateDistance(unit.m_x, unit.m_y);
                    if (distance > maxDistance)
                    {
                        maxDistance = distance;
                        farthestUnit = unit;
                    }
                }
            }

            return farthestUnit;
        }

        // 计算到目标位置的路径
        private List<PathNode> CalculatePathTo(int targetX, int targetY)
        {
            return pathfinder.FindPath(m_x, m_y, targetX, targetY);
        }

        // 沿着路径移动一步
        private void MoveAlongPath()
        {
            if (currentPath == null || currentPath.Count == 0) return;

            PathNode nextNode = currentPath[0];
            currentPath.RemoveAt(0);
            m_x = nextNode.x;
            m_y = nextNode.y;

            // 设置移动冷却（避免单位移动过快）
            moveCooldown = 2;
        }

        // 计算到指定位置的距离
        private int CalculateDistance(int x, int y)
        {
            return Math.Abs(m_x - x) + Math.Abs(m_y - y);
        }
    }

    class RFC2Map
    {
        public List<RFC2Plot> m_plot = new List<RFC2Plot>();

        public void Init()
        {
            for (int i = 0; i < 1000; i++)
            {
                for (int j = 0; j < 1000; j++)
                {
                    m_plot.Add(new RFC2Plot(i, j));
                }
            }
        }

        public void DoTurn()
        {
        }
    }

    class RFC2Team
    {
        public void DoTurn()
        {
        }
    }

    class RFC2Player
    {
        public List<RFC2City> m_city = new List<RFC2City>();
        public List<RFC2Unit> m_unit = new List<RFC2Unit>();
        public RFC2CivilizationType playerID = new RFC2CivilizationType();

        public void Init(int iCiv)
        {
            playerID.m_civilization = iCiv;
            for (int i = 0; i < 100; i++)
            {
                RFC2City rfc2City = new RFC2City();
                rfc2City.Init(i, i);
                rfc2City.eOwner = playerID;
                m_city.Add(rfc2City);
            }
            for (int i = 0; i < 100; i++)
            {
                RFC2Unit unit = new RFC2Unit();
                unit.Init(i, i);
                unit.eOwner = playerID;
                m_unit.Add(unit);
            }
        }

        public void DoTurn()
        {
            foreach (RFC2City city in m_city)
            {
                city.DoTurn();
            }
            foreach (RFC2Unit unit in m_unit)
            {
                unit.DoTurn();
            }
        }

        public List<RFC2Unit> GetUnits()
        {
            return m_unit;
        }
    }

    class RFC2Game
    {
        public RFC2Map m_map = new RFC2Map();
        public List<RFC2Player> m_player = new List<RFC2Player>();
        public long m_count;
        private int turnCount = 0; // 回合计数器

        public void Init()
        {
            for (int i = 0; i < 20; i++)
            {
                RFC2Player rfc2Player = new RFC2Player();
                rfc2Player.Init(i);
                m_player.Add(rfc2Player);

                foreach (RFC2City city in rfc2Player.m_city)
                {
                    city.SetGame(this);
                }

                // 设置单位的游戏引用
                foreach (RFC2Unit unit in rfc2Player.GetUnits())
                {
                    unit.SetGame(this);
                }
            }
            m_map.Init();
        }

        public void DoTurn()
        {
            turnCount++;
            m_count = 0;

            foreach (RFC2Player player in m_player)
            {
                player.DoTurn();
            }

            m_map.DoTurn();
            Console.WriteLine($"第 {turnCount} 回合完成，所有城市周围3格内的单位总数: {m_count}");
        }

        public List<RFC2Unit> GetAllUnits()
        {
            List<RFC2Unit> allUnits = new List<RFC2Unit>();
            foreach (RFC2Player player in m_player)
            {
                allUnits.AddRange(player.GetUnits());
            }
            return allUnits;
        }

        // 按区域获取单位（优化统计性能）
        public List<RFC2Unit> GetUnitsInRange(int x, int y, int range)
        {
            List<RFC2Unit> unitsInRange = new List<RFC2Unit>();
            int minX = Math.Max(0, x - range);
            int maxX = Math.Min(999, x + range);
            int minY = Math.Max(0, y - range);
            int maxY = Math.Min(999, y + range);

            foreach (RFC2Unit unit in GetAllUnits())
            {
                if (unit.m_x >= minX && unit.m_x <= maxX &&
                    unit.m_y >= minY && unit.m_y <= maxY)
                {
                    unitsInRange.Add(unit);
                }
            }
            return unitsInRange;
        }

        // 获取当前回合数
        public int GetTurnCount()
        {
            return turnCount;
        }
    }
}